/*
 * Copyright (c) 2020, Sensirion AG
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Sensirion AG nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * \file
 *
 * \brief Sensirion SHT4X driver implementation
 *
 * This module provides access to the SHT4X functionality over a generic I2C
 * interface. It supports measurements without clock stretching only.
 */

#include "bsp_sht4x.h"
#include "bsp_timer.h"
#include "stm32g0xx_hal.h"

#if defined(SHT4X_USE_HW_I2C)
#include "bsp_cpu_i2c2.h"
#endif

static uint8_t sht4x_cmd_measure           = SHT4X_CMD_MEASURE_HPM;
static uint16_t sht4x_cmd_measure_delay_us = SHT4X_MEASUREMENT_DURATION_USEC;

#define sensirion_sleep_usec(useconds)  bsp_DelayUS(useconds)


//================================================================//
#if defined(SHT4X_USE_SW_I2C)

#define SHT4X_SW_I2C_SCL_RCC()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define SHT4X_SW_I2C_SCL_PIN	    GPIO_PIN_11			/* 连接到SCL时钟线的GPIO */
#define SHT4X_SW_I2C_SCL_PORT       GPIOA

#define SHT4X_SW_I2C_SDA_RCC()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define SHT4X_SW_I2C_SDA_PIN	    GPIO_PIN_12			/* 连接到SDA数据线的GPIO */
#define SHT4X_SW_I2C_SDA_PORT       GPIOA


/* 定义读写SCL和SDA的宏 */
#define SHT4X_I2C_SCL_1()     HAL_GPIO_WritePin(SHT4X_SW_I2C_SCL_PORT,SHT4X_SW_I2C_SCL_PIN,GPIO_PIN_SET)	/* SCL = 1 */
#define SHT4X_I2C_SCL_0()     HAL_GPIO_WritePin(SHT4X_SW_I2C_SCL_PORT,SHT4X_SW_I2C_SCL_PIN,GPIO_PIN_RESET)			/* SCL = 0 */

#define SHT4X_I2C_SDA_1()     HAL_GPIO_WritePin(SHT4X_SW_I2C_SDA_PORT,SHT4X_SW_I2C_SDA_PIN,GPIO_PIN_SET)			/* SDA = 1 */
#define SHT4X_I2C_SDA_0()     HAL_GPIO_WritePin(SHT4X_SW_I2C_SDA_PORT,SHT4X_SW_I2C_SDA_PIN,GPIO_PIN_RESET)		/* SDA = 0 */

#define I2C_SDA_READ()  ((HAL_GPIO_ReadPin(SHT4X_SW_I2C_SDA_PORT, SHT4X_SW_I2C_SDA_PIN)) != GPIO_PIN_RESET)	/* 读SDA口线状态 */
#define I2C_SCL_READ()  ((HAL_GPIO_ReadPin(SHT4X_SW_I2C_SCL_PORT, SHT4X_SW_I2C_SCL_PIN)) != GPIO_PIN_RESET)	/* 读SCL口线状态 */

/*
*********************************************************************************************************
*	函 数 名: sht4x_sw_i2c_delay
*	功能说明: I2C总线位延迟，最快400KHz
*	形    参:  无
*	返 回 值: 无
*********************************************************************************************************
*/
static void sht4x_sw_i2c_delay(void)
{
    volatile uint8_t i = 0;

    /*　
    	实际应用选择400KHz左右的速率即可
    */
    for(i = 0; i < 30; i++);
}

/*******************************************************************************
* 名    称： bsp_i2c_Start
* 功    能： CPU发起I2C总线启动信号
* 入口参数： 无
* 出口参数： 无
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：  开始时序
 *            SCL ˉˉˉˉˉˉ\____
 *            SDA ˉˉˉˉ\______
 *                  |   |
 *                  START
*******************************************************************************/
static void sht4x_sw_i2c_start(void)
{
    /* 当SCL高电平时，SDA出现一个下跳沿表示I2C总线启动信号 */
    SHT4X_I2C_SDA_1();
    SHT4X_I2C_SCL_1();
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SDA_0();
    sht4x_sw_i2c_delay();

    SHT4X_I2C_SCL_0();
    sht4x_sw_i2c_delay();
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_stop
* 功    能： CPU发起I2C总线停止信号
* 入口参数： 无
* 出口参数： 无
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注： 停止时序
 *            SCL _____/ˉˉˉˉˉˉˉ
 *            SDA _________/ˉˉˉˉˉ
 *                       |   |
 *                       STOP
*******************************************************************************/
static void sht4x_sw_i2c_stop(void)
{
    /* 当SCL高电平时，SDA出现一个上跳沿表示I2C总线停止信号 */
    SHT4X_I2C_SDA_0();
    SHT4X_I2C_SCL_1();
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SDA_1();
    sht4x_sw_i2c_delay();
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_send_byte
* 功    能： CPU向I2C总线设备发送8bit数据
* 入口参数：  _ucByte ： 等待发送的字节
* 出口参数： 无
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：
*******************************************************************************/
void sht4x_sw_i2c_send_byte(uint8_t _ucByte)
{
    uint8_t i;

    /* 先发送字节的高位bit7 */
    for(i = 0; i < 8; i++)
    {
        if(_ucByte & 0x80)
        {
            SHT4X_I2C_SDA_1();
        }
        else
        {
            SHT4X_I2C_SDA_0();
        }
        sht4x_sw_i2c_delay();
        SHT4X_I2C_SCL_1();
        sht4x_sw_i2c_delay();
        SHT4X_I2C_SCL_0();
        if(i == 7)
        {
            SHT4X_I2C_SDA_1(); // 释放总线
        }
        _ucByte <<= 1;	/* 左移一个bit */
        sht4x_sw_i2c_delay();
    }
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_read_byte
* 功    能： CPU从I2C总线设备读取8bit数据
* 入口参数： 无
* 出口参数： 读到的数据
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：
*******************************************************************************/
uint8_t sht4x_sw_i2c_read_byte(void)
{
    uint8_t i;
    uint8_t value;

    /* 读到第1个bit为数据的bit7 */
    value = 0;
    for(i = 0; i < 8; i++)
    {
        value <<= 1;
        SHT4X_I2C_SCL_1();
        sht4x_sw_i2c_delay();
        if(I2C_SDA_READ())
        {
            value++;
        }
        SHT4X_I2C_SCL_0();
        sht4x_sw_i2c_delay();
    }
    return value;
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_wait_ack
* 功    能： CPU产生一个时钟，并读取器件的ACK应答信号
* 入口参数： 无
* 出口参数： 返回0表示正确应答，1表示无器件响应
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：
*******************************************************************************/
uint8_t sht4x_sw_i2c_wait_ack(void)
{
    uint8_t re;

    SHT4X_I2C_SDA_1();	/* CPU释放SDA总线 */
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SCL_1();	/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
    sht4x_sw_i2c_delay();
    if(I2C_SDA_READ())  	/* CPU读取SDA口线状态 */
    {
        re = 1;
    }
    else
    {
        re = 0;
    }
    SHT4X_I2C_SCL_0();
    sht4x_sw_i2c_delay();
    return re;
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_ack
* 功    能： CPU产生一个ACK信号
* 入口参数： 无
* 出口参数： 无
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：
*******************************************************************************/
void sht4x_sw_i2c_ack(void)
{
    SHT4X_I2C_SDA_0();	/* CPU驱动SDA = 0 */
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SCL_1();	/* CPU产生1个时钟 */
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SCL_0();
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SDA_1();	/* CPU释放SDA总线 */
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_no_ack
* 功    能： CPU产生1个NACK信号。
* 入口参数： 无
* 出口参数： 无
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：
*******************************************************************************/
void sht4x_sw_i2c_no_ack(void)
{
    SHT4X_I2C_SDA_1();	/* CPU驱动SDA = 1 */
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SCL_1();	/* CPU产生1个时钟 */
    sht4x_sw_i2c_delay();
    SHT4X_I2C_SCL_0();
    sht4x_sw_i2c_delay();
}

/*******************************************************************************
* 名    称： sht4x_sw_i2c_init
* 功    能： 配置I2C总线的GPIO，采用模拟IO的方式实现
* 入口参数： 无
* 出口参数： 无
* 作　　者： Roger-WY
* 创建日期： 2016-06-29
* 修    改：
* 修改日期：
* 备    注：
*******************************************************************************/
void sht4x_sw_i2c_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    SHT4X_SW_I2C_SCL_RCC();
    SHT4X_SW_I2C_SDA_RCC();	/* 打开GPIO时钟 */

    /*Configure GPIO pins */
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Pin = SHT4X_SW_I2C_SCL_PIN;
    HAL_GPIO_Init(SHT4X_SW_I2C_SCL_PORT, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = SHT4X_SW_I2C_SDA_PIN;
    HAL_GPIO_Init(SHT4X_SW_I2C_SDA_PORT, &GPIO_InitStruct);

    /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
    sht4x_sw_i2c_stop();
}

int8_t sht4x_sw_i2c_write(uint8_t address, const uint8_t* data, uint16_t count)
{
    int8_t ret;
    uint16_t i;

    sht4x_sw_i2c_start();

    sht4x_sw_i2c_send_byte(address << 1);
    ret = sht4x_sw_i2c_wait_ack();
    if(ret != NO_ERROR)
    {
        goto exit;                  //器件无响应
    }
    for(i = 0; i < count; i++)
    {
        sht4x_sw_i2c_send_byte(data[i]);
        ret = sht4x_sw_i2c_wait_ack();
        if(ret != NO_ERROR)
        {
            goto exit;                  //器件无响应
        }
    }
exit:
    sht4x_sw_i2c_stop();
    return ret;
}

int8_t sht4x_sw_i2c_read(uint8_t address, uint8_t* data, uint16_t count)
{
    int8_t ret;
    uint16_t i;

    sht4x_sw_i2c_start();

    sht4x_sw_i2c_send_byte((address << 1) | 1);
    ret = sht4x_sw_i2c_wait_ack();
    if(ret != NO_ERROR)
    {
        goto exit;                  //器件无响应
    }
    for(i = 0; i < count; i++)
    {
        data[i] = sht4x_sw_i2c_read_byte();
        if(i == (count - 1))
        {
            sht4x_sw_i2c_no_ack();
        }
        else
        {
            sht4x_sw_i2c_ack();
        }
    }
exit:
    sht4x_sw_i2c_stop();
    return ret;
}

#else
int8_t sht4x_hw_i2c_write(uint8_t address, const uint8_t* data, uint16_t count)
{
    int8_t ret;
    ret = HAL_I2C_Master_Transmit(&halI2c2, (address << 1), (uint8_t*)data, count, I2Cx_WAIT_TIMEOUT);
    return ret;
}

int8_t sht4x_hw_i2c_read(uint8_t address, uint8_t* data, uint16_t count)
{
    int8_t ret;
    ret = HAL_I2C_Master_Receive(&halI2c2, (address << 1) | 0x01, data, count, I2Cx_WAIT_TIMEOUT);
    return ret;
}
#endif



//================================================================//
/* 最终操作读取SHT4X I2C 接口 */
int8_t sensirion_i2c_write(uint8_t address, const uint8_t* data, uint16_t count)
{
#if defined(SHT4X_USE_SW_I2C)
    return (sht4x_sw_i2c_write(address, data, count));
#else
    return (sht4x_hw_i2c_write(address, data, count));
#endif
}

int8_t sensirion_i2c_read(uint8_t address, uint8_t* data, uint16_t count)
{
#if defined(SHT4X_USE_SW_I2C)
    return (sht4x_sw_i2c_read(address, data, count));
#else
    return (sht4x_hw_i2c_read(address, data, count));
#endif
}

void sensirion_i2c_init(void)
{
#if defined(SHT4X_USE_SW_I2C)
    sht4x_sw_i2c_init();
#else
    hal_I2c2Master_Init();
#endif
}

void sensirion_i2c_release(void)
{
#if defined(SHT4X_USE_SW_I2C)

#else

#endif
}


//================================================================//

uint16_t sensirion_bytes_to_uint16_t(const uint8_t* bytes)
{
    return (uint16_t)bytes[0] << 8 | (uint16_t)bytes[1];
}

uint32_t sensirion_bytes_to_uint32_t(const uint8_t* bytes)
{
    return (uint32_t)bytes[0] << 24 | (uint32_t)bytes[1] << 16 |
           (uint32_t)bytes[2] << 8 | (uint32_t)bytes[3];
}

float sensirion_bytes_to_float(const uint8_t* bytes)
{
    union
    {
        uint32_t u32_value;
        float float32;
    } tmp;

    tmp.u32_value = sensirion_bytes_to_uint32_t(bytes);
    return tmp.float32;
}

uint8_t sensirion_common_generate_crc(const uint8_t* data, uint16_t count)
{
    uint16_t current_byte;
    uint8_t crc = CRC8_INIT;
    uint8_t crc_bit;

    /* calculates 8-Bit checksum with given polynomial */
    for(current_byte = 0; current_byte < count; ++current_byte)
    {
        crc ^= (data[current_byte]);
        for(crc_bit = 8; crc_bit > 0; --crc_bit)
        {
            if(crc & 0x80)
                crc = (crc << 1) ^ CRC8_POLYNOMIAL;
            else
                crc = (crc << 1);
        }
    }
    return crc;
}

int8_t sensirion_common_check_crc(const uint8_t* data, uint16_t count,
                                  uint8_t checksum)
{
    if(sensirion_common_generate_crc(data, count) != checksum)
        return STATUS_FAIL;
    return NO_ERROR;
}

int16_t sensirion_i2c_general_call_reset(void)
{
    const uint8_t data = 0x06;
    return sensirion_i2c_write(0, &data, (uint16_t)sizeof(data));
}

uint16_t sensirion_fill_cmd_send_buf(uint8_t* buf, uint16_t cmd,
                                     const uint16_t* args, uint8_t num_args)
{
    uint8_t crc;
    uint8_t i;
    uint16_t idx = 0;

    buf[idx++] = (uint8_t)((cmd & 0xFF00) >> 8);
    buf[idx++] = (uint8_t)((cmd & 0x00FF) >> 0);

    for(i = 0; i < num_args; ++i)
    {
        buf[idx++] = (uint8_t)((args[i] & 0xFF00) >> 8);
        buf[idx++] = (uint8_t)((args[i] & 0x00FF) >> 0);

        crc = sensirion_common_generate_crc((uint8_t*)&buf[idx - 2],
                                            SENSIRION_WORD_SIZE);
        buf[idx++] = crc;
    }
    return idx;
}

int16_t sensirion_i2c_read_words_as_bytes(uint8_t address, uint8_t* data,
        uint16_t num_words)
{
    int16_t ret;
    uint16_t i, j;
    uint16_t size = num_words * (SENSIRION_WORD_SIZE + CRC8_LEN);
    uint16_t word_buf[SENSIRION_MAX_BUFFER_WORDS];
    uint8_t* const buf8 = (uint8_t*)word_buf;

    ret = sensirion_i2c_read(address, buf8, size);
    if(ret != NO_ERROR)
        return ret;

    /* check the CRC for each word */
    for(i = 0, j = 0; i < size; i += SENSIRION_WORD_SIZE + CRC8_LEN)
    {

        ret = sensirion_common_check_crc(&buf8[i], SENSIRION_WORD_SIZE,
                                         buf8[i + SENSIRION_WORD_SIZE]);
        if(ret != NO_ERROR)
            return ret;

        data[j++] = buf8[i];
        data[j++] = buf8[i + 1];
    }

    return NO_ERROR;
}

int16_t sensirion_i2c_read_words(uint8_t address, uint16_t* data_words,
                                 uint16_t num_words)
{
    int16_t ret;
    uint8_t i;
    const uint8_t* word_bytes;

    ret = sensirion_i2c_read_words_as_bytes(address, (uint8_t*)data_words,
                                            num_words);
    if(ret != NO_ERROR)
        return ret;

    for(i = 0; i < num_words; ++i)
    {
        word_bytes = (uint8_t*)&data_words[i];
        data_words[i] = ((uint16_t)word_bytes[0] << 8) | word_bytes[1];
    }

    return NO_ERROR;
}

int16_t sensirion_i2c_write_cmd(uint8_t address, uint16_t command)
{
    uint8_t buf[SENSIRION_COMMAND_SIZE];

    sensirion_fill_cmd_send_buf(buf, command, NULL, 0);
    return sensirion_i2c_write(address, buf, SENSIRION_COMMAND_SIZE);
}

int16_t sensirion_i2c_write_cmd_with_args(uint8_t address, uint16_t command,
        const uint16_t* data_words,
        uint16_t num_words)
{
    uint8_t buf[SENSIRION_MAX_BUFFER_WORDS];
    uint16_t buf_size;

    buf_size = sensirion_fill_cmd_send_buf(buf, command, data_words, num_words);
    return sensirion_i2c_write(address, buf, buf_size);
}

int16_t sensirion_i2c_delayed_read_cmd(uint8_t address, uint16_t cmd,
                                       uint32_t delay_us, uint16_t* data_words,
                                       uint16_t num_words)
{
    int16_t ret;
    uint8_t buf[SENSIRION_COMMAND_SIZE];

    sensirion_fill_cmd_send_buf(buf, cmd, NULL, 0);
    ret = sensirion_i2c_write(address, buf, SENSIRION_COMMAND_SIZE);
    if(ret != NO_ERROR)
        return ret;

    if(delay_us)
        sensirion_sleep_usec(delay_us);

    return sensirion_i2c_read_words(address, data_words, num_words);
}

int16_t sensirion_i2c_read_cmd(uint8_t address, uint16_t cmd,
                               uint16_t* data_words, uint16_t num_words)
{
    return sensirion_i2c_delayed_read_cmd(address, cmd, 0, data_words,
                                          num_words);
}


int16_t sht4x_measure_blocking_read(int32_t* temperature, int32_t* humidity)
{
    int16_t ret;

    ret = sht4x_measure();
    if(ret)
        return ret;
    sensirion_sleep_usec(sht4x_cmd_measure_delay_us);
    return sht4x_read(temperature, humidity);
}

int16_t sht4x_measure(void)
{
    return sensirion_i2c_write(SHT4X_ADDRESS, &sht4x_cmd_measure, 1);
}

int16_t sht4x_read(int32_t* temperature, int32_t* humidity)
{
    uint16_t words[2];
    int16_t ret = sensirion_i2c_read_words(SHT4X_ADDRESS, words,
                                           SENSIRION_NUM_WORDS(words));
    /**
     * formulas for conversion of the sensor signals, optimized for fixed point
     * algebra:
     * Temperature = 175 * S_T / 65535 - 45
     * Relative Humidity = 125 * (S_RH / 65535) - 6
     */
    *temperature = ((21875 * (int32_t)words[0]) >> 13) - 45000;
    *humidity = ((15625 * (int32_t)words[1]) >> 13) - 6000;

    return ret;
}


void sht4x_enable_low_power_mode(uint8_t enable_low_power_mode)
{
    if(enable_low_power_mode)
    {
        sht4x_cmd_measure = SHT4X_CMD_MEASURE_LPM;
        sht4x_cmd_measure_delay_us = SHT4X_MEASUREMENT_DURATION_LPM_USEC;
    }
    else
    {
        sht4x_cmd_measure = SHT4X_CMD_MEASURE_HPM;
        sht4x_cmd_measure_delay_us = SHT4X_MEASUREMENT_DURATION_USEC;
    }
}

int16_t sht4x_read_serial(uint32_t* serial)
{
    const uint8_t cmd = SHT4X_CMD_READ_SERIAL;
    int16_t ret;
    uint16_t serial_words[SENSIRION_NUM_WORDS(*serial)];

    ret = sensirion_i2c_write(SHT4X_ADDRESS, &cmd, 1);
    if(ret)
        return ret;

    sensirion_sleep_usec(SHT4X_CMD_DURATION_USEC);
    ret = sensirion_i2c_read_words(SHT4X_ADDRESS, serial_words,
                                   SENSIRION_NUM_WORDS(serial_words));
    *serial = ((uint32_t)serial_words[0] << 16) | serial_words[1];

    return ret;
}

int16_t sht4x_probe(void)
{
    uint32_t serial = 0;

    return sht4x_read_serial(&serial);
}

uint8_t sht4x_get_configured_address(void)
{
    return SHT4X_ADDRESS;
}

int8_t bsp_Sht4xInit(void)
{
    int8_t ret = STATUS_FAIL;
    uint8_t u8TimeoutCnt = 0;
    sensirion_i2c_init();

//    /* Busy loop for initialization, because the main loop does not work without
//     * a sensor.
//     */
//    while(sht4x_probe() != STATUS_OK)
//    {
//        if(u8TimeoutCnt++ > 3)
//        {
//            break;
//        }
//        //"SHT sensor probing failed"
//        sensirion_sleep_usec(1000000); /* sleep 1s */
//    }

//    if(u8TimeoutCnt > 3)
    if(sht4x_probe() != STATUS_OK)
    {
        ret = STATUS_FAIL;
    }
    else
    {
        ret = STATUS_OK;
    }

    return ret;
}

int8_t bsp_Sht4xReadTempAndHumi(sht4xValTypeDef_t* pSht4xVal)
{
    int32_t temperature, humidity;
    int8_t ret = STATUS_FAIL;

    /* Measure temperature and relative humidity and store into variables
     * temperature, humidity (each output multiplied by 1000).
     */
    ret = sht4x_measure_blocking_read(&temperature, &humidity);
    if(ret == STATUS_OK)
    {

        pSht4xVal->fTemp  = temperature / 1000.0f;
        pSht4xVal->fHumi  = humidity / 1000.0f;
        pSht4xVal->iTemp  = (int16_t)(pSht4xVal->fTemp * 10);   //放大10倍，保留小数点后面一位
        pSht4xVal->uiHumi = (uint16_t)(pSht4xVal->fHumi * 10);  //放大10倍，保留小数点后面一位
    }

    return (ret);
}
